// GamePanel
//
// January 14, 2010
package lightspeed.Media.Graphics;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;

import lightspeed.Network.LightClient;
import lightspeed.Backend.GameManager;
import lightspeed.Media.Audio.*;

public class GamePanel extends JPanel
{
	boolean running;
	private BufferedImage[][] shipImages;	//holds ship images
	private BufferedImage[] explosionImages;
	
	private BufferedImage background;
	private BufferedImage bulletBlue, bulletRed;
	
	private BufferedImage blueFlag, blueBase;
	private BufferedImage redFlag, redBase;
	
	private BufferedImage blueWin, redWin;
	
	private int blueBaseX, blueBaseY;
	private int redBaseX, redBaseY;
	
	private short[] shipExploding;
	
	public GraphicsUpdater gu;
	public short restart = 0;
	
	private short scoreRed, scoreBlue;
	
	public GamePanel()
	{
		setLayout(null);
		setBackground(Color.black);
		
		blueBaseX = -5; blueBaseY = -5;
		redBaseX = -10; redBaseY = -10;
		
		shipExploding = new short[20];
		
		shipImages = new BufferedImage[36][2];
		//load images for ships
		for(int i = 0; i < shipImages.length; ++i)
		{
			try
			{
				shipImages[i][0] = ImageIO.read(new File("images/ships/f" + i + "0.png"));
				shipImages[i][1] = ImageIO.read(new File("images/ships/r" + i + "0.png"));
			}
			catch(IOException e)
			{
				System.err.println("Couldn't find ship image.");
				//e.printStackTrace();
			}
		}
		//
		
		try
		{
			background = ImageIO.read(new File("images/stars.bmp"));
			
			explosionImages = new BufferedImage[19];
			for(int i = 0; i < explosionImages.length; ++i)
			{
				explosionImages[i] = ImageIO.read(new File("images/explosions/" + (i+1) + ".png"));
			}
			bulletBlue = ImageIO.read(new File("images/bullet02.png"));
			bulletRed = ImageIO.read(new File("images/bullet00.png"));
			
			blueFlag = ImageIO.read(new File("images/Italy.gif"));
			redFlag = ImageIO.read(new File("images/Germany.gif"));
			
			blueBase = ImageIO.read(new File("images/Neptune.gif"));
			redBase = ImageIO.read(new File("images/Mercury.gif"));
			
			blueWin = ImageIO.read(new File("images/bluewins.png"));
			redWin = ImageIO.read(new File("images/redwins.png"));
		}
		catch(IOException e)
		{
			System.err.println("Couldn't find images.");
			//e.printStackTrace();
		}
		
		running = true;
		gu = this.new GraphicsUpdater();
		gu.start();
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		//draw stuff
		if(WindowManager.client != null && LightClient.spacket != null)
		{
			//draw background
			g.setColor(Color.WHITE);
			g.drawImage(background, WindowManager.WINDOW_WIDTH/2 - (LightClient.spacket.shipPositions[LightClient.clientNumber][0]), WindowManager.WINDOW_HEIGHT/2 + (LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - background.getHeight(), null);
			g.drawRect(WindowManager.WINDOW_WIDTH/2 - (LightClient.spacket.shipPositions[LightClient.clientNumber][0]), WindowManager.WINDOW_HEIGHT/2 + (LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - 3000, 3000, 3000);
			//
			
			//draw bases
			if(blueBaseX < 0 || LightClient.spacket.gameOver == 1)
			{
				blueBaseX = (int)(LightClient.spacket.blueFlagX) + 15;
				blueBaseY = (int)(LightClient.spacket.blueFlagY) + 15;
				
				redBaseX = (int)(LightClient.spacket.redFlagX) + 15;
				redBaseY = (int)(LightClient.spacket.redFlagY) + 15;
			}
			/*
			if(LightClient.spacket.gameOver == 1)
			{
				if(scoreBlue > scoreRed)
					g.drawImage(blueWin, WindowManager.WINDOW_WIDTH/2 - blueWin.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - blueWin.getHeight(), null);
				else
					g.drawImage(redWin, WindowManager.WINDOW_WIDTH/2 - redWin.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - redWin.getHeight(), null);
				restart = 1;
				gu.stop();
			}*/
			
			g.drawImage(blueBase, WindowManager.WINDOW_WIDTH/2 + blueBaseX - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - blueBase.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - blueBaseY + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - blueBase.getHeight()/2, null);
			
			g.drawImage(redBase, WindowManager.WINDOW_WIDTH/2 + redBaseX - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - redBase.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - redBaseY + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - redBase.getHeight()/2, null);
			//
			
			//draw flags
			g.drawImage(blueFlag, WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.blueFlagX) - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - blueFlag.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.blueFlagY) + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - blueFlag.getHeight()/2, null);
			
			g.drawImage(redFlag, WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.redFlagX) - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - redFlag.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.redFlagY) + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - redFlag.getHeight()/2, null);
			//
			
			//draw other ships
			for(int i = 0; i < LightClient.spacket.shipPositions.length; ++i)
			{
				if(LightClient.spacket.shipPositions[i][0] >= 0 && i != LightClient.clientNumber)
				{
					g.drawImage(shipImages[LightClient.spacket.shipPositions[i][2]][(LightClient.spacket.shipPositions[i][3] & 1)], WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.shipPositions[i][0]) - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - shipImages[0][0].getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.shipPositions[i][1]) + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - shipImages[0][0].getHeight()/2, null);
					
					if((LightClient.spacket.shipPositions[i][3] & 2) == 2)// check if ship is dead
					{
						g.drawString("dead", WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.shipPositions[i][0]) - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - shipImages[0][0].getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.shipPositions[i][1]) + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - shipImages[0][0].getHeight()/2);
					}
					else
					{
						shipExploding[i] = 0;
					}
					
					//starting explosion (sound and image loop)
					if(((LightClient.spacket.shipPositions[i][3] & 2) == 2) && ((shipExploding[i] & 1) == 0))
					{
						new SoundPlayer("audio/explode.wav").play();
					}
					//
					
					//draw player names under ships
					if(LightClient.spacket.messages != null && LightClient.spacket.messages[i] != null)
					{
						String name = LightClient.spacket.messages[i];
						for(int j = 0; j < LightClient.spacket.messages[i].length(); ++j)
						{
							if(LightClient.spacket.messages[i].charAt(j) == ':')
							{
								name = ("<" + name.substring(0, j) + ">");
								break;
							}
						}
						if(((int)(LightClient.spacket.shipPositions[i][3]) & 1) == 1) //check if red team
						{
							g.setColor(Color.RED);
						}
						else
						{
							g.setColor(Color.BLUE);
						}
					
						g.drawString(name, WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.shipPositions[i][0]) - (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - shipImages[0][0].getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.shipPositions[i][1]) + (int)(LightClient.spacket.shipPositions[LightClient.clientNumber][1]) + shipImages[0][0].getHeight()/2);
					}
					//
					
				}
			}
			//
			
			//draw bullets
			for(int i = 0; i < LightClient.spacket.bulletPositions.length; ++i)
			{
				if(LightClient.spacket.bulletPositions[i][0] != 0 && LightClient.spacket.bulletPositions[i][1] != 0)
				{
					if(((int)(LightClient.spacket.bulletPositions[i][2]) & 1) == 1)
						g.drawImage(bulletRed, WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.bulletPositions[i][0]) - (LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - bulletRed.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.bulletPositions[i][1]) + (LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - bulletRed.getHeight()/2, null);
					else
						g.drawImage(bulletBlue, WindowManager.WINDOW_WIDTH/2 + (int)(LightClient.spacket.bulletPositions[i][0]) - (LightClient.spacket.shipPositions[LightClient.clientNumber][0]) - bulletBlue.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - (int)(LightClient.spacket.bulletPositions[i][1]) + (LightClient.spacket.shipPositions[LightClient.clientNumber][1]) - bulletBlue.getHeight()/2, null);
				}
			}
			//
			
			//draw ship
			g.drawImage(shipImages[LightClient.spacket.shipPositions[LightClient.clientNumber][2]][(LightClient.spacket.shipPositions[LightClient.clientNumber][3]) & 1], WindowManager.WINDOW_WIDTH/2 - shipImages[0][0].getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - shipImages[0][0].getHeight()/2, null);
			
			if((LightClient.spacket.shipPositions[LightClient.clientNumber][3] & 2) == 2)// check if ship is dead
			{
				g.drawString("dead", WindowManager.WINDOW_WIDTH/2 - shipImages[0][0].getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - shipImages[0][0].getHeight()/2);
			}
			else
			{
				shipExploding[LightClient.clientNumber] = 0;
			}
			
			//starting explosion (sound and image loop)
			if(((LightClient.spacket.shipPositions[LightClient.clientNumber][3] & 2) == 2) && ((shipExploding[LightClient.clientNumber] & 1) == 0))
			{
				new SoundPlayer("audio/explode.wav").play();
			}
			
			if(LightClient.spacket.messages != null && LightClient.spacket.messages[LightClient.clientNumber] != null)
			{
				String name = LightClient.spacket.messages[LightClient.clientNumber];
				for(int j = 0; j < LightClient.spacket.messages[LightClient.clientNumber].length(); ++j)
				{
					if(LightClient.spacket.messages[LightClient.clientNumber].charAt(j) == ':')
					{
						name = ("<" + name.substring(0, j) + ">");
						break;
					}
				}
				if(((int)(LightClient.spacket.shipPositions[LightClient.clientNumber][3]) & 1) == 1) //check if red team
				{
					g.setColor(Color.RED);
				}
				else
				{
					g.setColor(Color.BLUE);
				}
			
				g.drawString(name, WindowManager.WINDOW_WIDTH/2 - shipImages[0][0].getWidth()/2, WindowManager.WINDOW_HEIGHT/2 + shipImages[0][0].getHeight()/2);
			}
			//
			
			if(LightClient.spacket.gameOver == 1)
			{
				if(scoreBlue > scoreRed)
					g.drawImage(blueWin, WindowManager.WINDOW_WIDTH/2 - blueWin.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - blueWin.getHeight()/2, null);
				else
					g.drawImage(redWin, WindowManager.WINDOW_WIDTH/2 - redWin.getWidth()/2, WindowManager.WINDOW_HEIGHT/2 - redWin.getHeight()/2, null);
				restart = 1;
				gu.stop();
			}
			
			//draw scores
			g.setColor(Color.WHITE);
			g.drawString(("Blue Team: " + LightClient.spacket.scores[0] + " || Red Team: " + LightClient.spacket.scores[1]), 25, 25);
			scoreRed = LightClient.spacket.scores[1];
			scoreBlue = LightClient.spacket.scores[0];
			//
			
		}
		//
	}
	
	public void startGraphics()
	{
		gu = new GraphicsUpdater();
		gu.start();
	}
	
	
	//PRIVATE CLASSES//
	
	private class GraphicsUpdater extends Thread
	{
		private int frameSpeed = GameManager.GAME_SPEED;
		
		public void run()
		{
			while(running)
			{
				int t = (int)System.currentTimeMillis(); //get current time
				
				if(WindowManager.currentPanel == WindowManager.GAME_PANEL)
				{
					//System.out.println("frames running");
					repaint();
				}
				
				//System.out.println((int)System.currentTimeMillis() - t); //for testing
				if((int)System.currentTimeMillis() - t > frameSpeed) //check if repaint took longer than frameSpeed
				{
					frameSpeed = 5; //minimum wait
				}
				else
				{
					frameSpeed = frameSpeed - ((int)System.currentTimeMillis() - t); //subtract time difference from frameSpeed (wait time until next frame)
				}
				
				try
				{
					Thread.sleep(frameSpeed);
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}
				
				frameSpeed = GameManager.GAME_SPEED; //reset framespeed variable
			}
		}
	}
}
